package com.common.playing.apps.comm.ui.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.common.kankan.wheel.widget.OnWheelChangedListener;
import com.common.kankan.wheel.widget.OnWheelScrollListener;
import com.common.kankan.wheel.widget.Range;
import com.common.kankan.wheel.widget.WheelView;
import com.common.kankan.wheel.widget.adapters.NumericWheelAdapter;
import com.common.kankan.wheel.widget.adapters.WheelViewAdapter;
import com.common.playing.apps.comm.listener.OnDatePickerChangeListener;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import width.hgk.wanwan.R;


/**
 * 日期选择控件
 * <p>
 * 日期控件的数据适配器请使用DateNumericAdapter
 * 
 * @author pengxh
 * 
 */
public class DatePickerView extends LinearLayout {

	private final String TAG = "BabytreeDatePicker";

	private String dateFormat = "yyyy-MM-dd";
	private SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);

	/**
	 * 月份滚轮
	 */
	private WheelView monthWheelView;

	/**
	 * 年份滚轮
	 */
	private WheelView yearWheelView;

	/**
	 * 天 滚轮
	 */
	private WheelView dayWheelView;

	/**
	 * 左侧取消按钮
	 */
	private Button btnCancel;

	/**
	 * 右侧确定按钮
	 */
	private Button btnSure;

	/**
	 * 中间时间Label
	 */
	private TextView tvShowTime;

	/**
	 * 顶部的bar条
	 * <p>
	 * 包括操作按钮和时间Label
	 */
	private View mLabelBar;

	private long mLastTimeMills;

	private Context mContext;

	private DatePickerView mDatePicker;

	private OnDatePickerChangeListener onDatePickerChangeListener;

	private WheelViewAdapter yearAdapter, monthAdapter, dayAdapter;

	public DatePickerView(Context context) {
		super(context);
		mContext = context;
	}

	public DatePickerView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		init(mContext);
	}

	/**
	 * 初始化
	 * 
	 * @param context
	 */
	private void init(Context context) {

		mDatePicker = this;

		yearWheelView = (WheelView) findViewById(R.id.year);
		monthWheelView = (WheelView) findViewById(R.id.month);
		dayWheelView = (WheelView) findViewById(R.id.day);

		mLabelBar = findViewById(R.id.operatorLaberBar);

		btnCancel = (Button) findViewById(R.id.btnCancelDatePicker);
		btnSure = (Button) findViewById(R.id.btnSureDatePicker);
		tvShowTime = (TextView) findViewById(R.id.tvShowTimeDatePicker);

		// Cycle 默认设置为循环
		yearWheelView.setCyclic(true);
		monthWheelView.setCyclic(true);
		dayWheelView.setCyclic(true);

		// 添加时间变动监听
		monthWheelView.addChangingListener(onWheelChangeListener);
		yearWheelView.addChangingListener(onWheelChangeListener);
		dayWheelView.addChangingListener(onWheelChangeListener);

		// 添加滚动监听
		monthWheelView.addScrollingListener(onWheelScrollListener);
		yearWheelView.addScrollingListener(onWheelScrollListener);
		dayWheelView.addScrollingListener(onWheelScrollListener);

		// 设置可见items条数
		setVisibeItems(5);

	}

	/**
	 * 显示当前最新时间到timeLable
	 * <p>
	 * 获取最新时间的毫秒数
	 */
	private long obtainCurrentTimeMills() {
		int minYear = getViewAdapter(yearWheelView).getMinValue();
		int minMonth = getViewAdapter(monthWheelView).getMinValue();
		int minDay = getViewAdapter(dayWheelView).getMinValue();
		int currYear = minYear + yearWheelView.getCurrentItem();
		int currMonth = minMonth + monthWheelView.getCurrentItem();
		int currDay = minDay + dayWheelView.getCurrentItem();

		Calendar currCal = Calendar.getInstance(Locale.CHINA);
		currCal.set(Calendar.YEAR, currYear);
		currCal.set(Calendar.MONTH, (currMonth - 1));
		currCal.set(Calendar.DAY_OF_MONTH, 1);
		// 防止出现所选天数大于所选月数应该的天数，导致月份自动+1问题
		int maxDays = currCal.getActualMaximum(Calendar.DAY_OF_MONTH);
		currDay = (currDay > maxDays) ? maxDays : currDay;
		currCal.set(Calendar.DAY_OF_MONTH, currDay);
		return currCal.getTimeInMillis();
	}

	/**
	 * 监听日期控件时间变动
	 * <p>
	 * 年、月、日
	 */
	private OnWheelChangedListener onWheelChangeListener = new OnWheelChangedListener() {
		public void onChanged(WheelView wheel, int oldValue, int newValue) {
			mLastTimeMills = obtainCurrentTimeMills();
			if (null != onDatePickerChangeListener) {
				onDatePickerChangeListener.onChanging(mDatePicker, mLastTimeMills);
			}
			showTimeLable(mLastTimeMills);
		}
	};

	/**
	 * 监听控件的滚动
	 * <p>
	 * 年、月、日
	 */
	private OnWheelScrollListener onWheelScrollListener = new OnWheelScrollListener() {

		@Override
		public void onScrollingStarted(WheelView wheel) {
			Log.d("DatePickerView","滚动开始");

			if (null != onDatePickerChangeListener) {
				onDatePickerChangeListener.onChangeStart(mDatePicker, obtainCurrentTimeMills());
			}
		}

		@Override
		public void onScrollingFinished(WheelView wheel) {
			Log.d("DatePickerView","滚动结束");
			if (null != onDatePickerChangeListener) {
				onDatePickerChangeListener.onChangeEnd(mDatePicker, obtainCurrentTimeMills());
			}
		}
	};

	/**
	 * 更新适配器
	 * 
	 * @param yearAdapter
	 * @param monthAdapter
	 * @param dayAdapter
	 */
	private void refreshAdapter(WheelViewAdapter yearAdapter, WheelViewAdapter monthAdapter, WheelViewAdapter dayAdapter) {
		this.yearAdapter = yearAdapter;
		this.monthAdapter = monthAdapter;
		this.dayAdapter = dayAdapter;
	}

	/**
	 * 显示时间
	 * 
	 * @param timeMills
	 */
	private void showTimeLable(long timeMills) {
		tvShowTime.setText(sdf.format(new Date(timeMills)));
	}

	// -------------------------------API----------------------

	/**
	 * 获取适配器
	 */
	public NumericWheelAdapter getViewAdapter(WheelView wheelView) {
		if (null != wheelView) {
			return (NumericWheelAdapter) wheelView.getViewAdapter();
		}
		return null;
	}

	/**
	 * 获取年份的WheelView
	 * 
	 * @return
	 */
	public WheelView getWheelView4Year() {
		return yearWheelView;
	}

	/**
	 * 获取月份的WheelView
	 * 
	 * @return
	 */
	public WheelView getWheelView4Month() {
		return monthWheelView;
	}

	/**
	 * 获取日的WheelView
	 * 
	 * @return
	 */
	public WheelView getWheelView4Day() {
		return dayWheelView;
	}

	/**
	 * 设置时间显示格式
	 * 
	 * @param fomat
	 */
	@SuppressLint("SimpleDateFormat")
	public void setTimeFormat(String fomat) {
		if (!TextUtils.isEmpty(fomat)) {
			this.dateFormat = fomat;
			sdf = new SimpleDateFormat(dateFormat);
		}
	}

	/**
	 * 添加日期选择控件时间变动监听
	 * 
	 * @param onDatePickerChangeListener
	 */
	public void setDatePickerChangeListener(OnDatePickerChangeListener onDatePickerChangeListener) {
		if (null != onDatePickerChangeListener) {
			this.onDatePickerChangeListener = onDatePickerChangeListener;
		}
	}

	/**
	 * 设置取消按钮监听
	 */
	public void setNegativeListener(OnClickListener onNegativeClickListener) {
		btnCancel.setOnClickListener(onNegativeClickListener);
	}

	/**
	 * 设置确定按钮监听
	 *
	 * @param onPositiveClickListener
	 */
	public void setPositiveListener(OnClickListener onPositiveClickListener) {
		btnSure.setOnClickListener(onPositiveClickListener);
	}

	/**
	 * 将所有设置循环显示(年、月、日)
	 * 
	 * @param isCyclic
	 */
	public void setCyclic(boolean isCyclic) {
		setYearCyclic(isCyclic);
		setMonthCyclic(isCyclic);
		setDayCyclic(isCyclic);
	}

	/**
	 * 设置年循环
	 * 
	 * @param isCyclic
	 */
	public void setYearCyclic(boolean isCyclic) {
		yearWheelView.setCyclic(isCyclic);
	}

	/**
	 * 设置月循环
	 * 
	 * @param isCyclic
	 */
	public void setMonthCyclic(boolean isCyclic) {
		monthWheelView.setCyclic(isCyclic);
	}

	/**
	 * 设置日循环
	 * 
	 * @param isCyclic
	 */
	public void setDayCyclic(boolean isCyclic) {
		dayWheelView.setCyclic(isCyclic);
	}

	/**
	 * 设置可见items的条数
	 * 
	 * @param counts
	 */
	public void setVisibeItems(int counts) {
		if (counts > 0) {
			yearWheelView.setVisibleItems(counts);
			monthWheelView.setVisibleItems(counts);
			dayWheelView.setVisibleItems(counts);
		}
	}

	/**
	 * 显示顶部标签、操作栏
	 */
	public void showLabelBar() {
		mLabelBar.setVisibility(View.VISIBLE);
	}

	/**
	 * 隐藏顶部标签、操作栏
	 */
	public void hideLabelBar() {
		mLabelBar.setVisibility(View.GONE);
	}

	/**
	 * 获取DatePicker当前时间的毫秒数
	 * 
	 * @return
	 */
	public long getLatestTimeMills() {
		return mLastTimeMills;
	}

	/**
	 * 获取左侧取消按钮
	 * 
	 * @return
	 */
	public Button getNegativeButton() {
		return btnCancel;
	}

	/**
	 * 获取右侧确定按钮
	 * 
	 * @return
	 */
	public Button getPositiveButton() {
		return btnSure;
	}

	/**
	 * 获取时间显示Label TextView
	 * 
	 * @return
	 */
	public TextView getTimeLabel() {
		return tvShowTime;
	}

	/**
	 * 设置时间Label字体颜色
	 * 
	 * @param color
	 */
	public void setTimeLabelTextColor(int color) {
		tvShowTime.setTextColor(color);
	}

	/**
	 * 设置时间Label字体大小
	 * 
	 * @param size
	 */
	public void setTimeLabelTextSize(float size) {
		tvShowTime.setTextSize(size);
	}

	/**
	 * 初始化适配器&刷新适配器
	 * 
	 * @param yearAdapter
	 * @param monthAdapter
	 * @param dayAdapter
	 */
	public void initAdapter(WheelViewAdapter yearAdapter, WheelViewAdapter monthAdapter, WheelViewAdapter dayAdapter) {

		refreshAdapter(yearAdapter, monthAdapter, dayAdapter);

		yearWheelView.setViewAdapter(yearAdapter);
		monthWheelView.setViewAdapter(monthAdapter);
		dayWheelView.setViewAdapter(dayAdapter);
	}

	/**
	 * 刷新到需要显示的日期
	 * 
	 * @param displayCalendar
	 *            需要滚动到的日期（年、月、日）
	 * @param range
	 *            此范围为当前年份的有效范围（月份和日不需要）
	 */
	public void refreshItemsScrollTo(Calendar displayCalendar, Range range) {
		// TODO
		// if ((year - range.start) > (count - 1)) {
		// }
		yearWheelView.setCurrentItem(displayCalendar.get(Calendar.YEAR) - range.start);
		monthWheelView.setCurrentItem(displayCalendar.get(Calendar.MONTH));
		dayWheelView.setCurrentItem(displayCalendar.get(Calendar.DAY_OF_MONTH) - 1);
	}

	/**
	 * 手动刷新
	 */
	public void refresh() {
		WheelView[] wheels = { yearWheelView, monthWheelView, dayWheelView };
		for (WheelView wheelView : wheels) {
			int currItem = wheelView.getCurrentItem();
			wheelView.setCurrentItem(currItem - 1);
			wheelView.setCurrentItem(currItem);
		}
	}

	/**
	 * 刷新到需要显示的日期
	 * 
	 * @param displayMills
	 *            需要滚动到的日期对应的毫秒数
	 * @param range
	 */
	public void refreshItemsScrollTo(long displayMills, Range range) {

		Calendar displayCalendar = Calendar.getInstance(Locale.CHINA);
		displayCalendar.setTimeInMillis(displayMills);

		yearWheelView.setCurrentItem(displayCalendar.get(Calendar.YEAR) - range.start);
		monthWheelView.setCurrentItem(displayCalendar.get(Calendar.MONTH));
		dayWheelView.setCurrentItem(displayCalendar.get(Calendar.DAY_OF_MONTH) - 1);
	}
}
